package com.vegetable.modules.service.stock.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vegetable.modules.entity.inbound.PackDelivery;
import com.vegetable.modules.entity.inbound.PackDeliveryDetail;
import com.vegetable.modules.entity.outbound.SalesOrderDetailStock;
import com.vegetable.modules.entity.stock.CostWeightChangeSource;
import com.vegetable.modules.entity.stock.Stock;
import com.vegetable.modules.mapper.inbound.PackDeliveryDetailMapper;
import com.vegetable.modules.service.inbound.IPackDeliveryService;
import com.vegetable.modules.service.outbound.ISalesOrderDetailStockService;
import com.vegetable.modules.service.stock.IChainCostChangeService;
import com.vegetable.modules.service.stock.ICostWeightChangeSourceService;
import com.vegetable.modules.service.stock.IStockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 连锁成本变化服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-03-21
 */
@Slf4j
@Service
public class ChainCostChangeServiceImpl implements IChainCostChangeService {

    @Resource
    private IStockService stockService;

    @Autowired
    private ICostWeightChangeSourceService costWeightChangeSourceService;

    @Autowired
    private IPackDeliveryService packDeliveryService;
    
    @Autowired
    private PackDeliveryDetailMapper packDeliveryDetailMapper;

    @Autowired
    private ISalesOrderDetailStockService salesOrderDetailStockService;

    @Override
    public void handleChainCostChange(CostWeightChangeSource rootChange, Stock affectedStock, Stock originalStock) {
        try {
            log.info("开始处理连锁成本变化，rootChange ID: {}, affectedStock ID: {}", 
                rootChange != null ? rootChange.getId() : "null", 
                affectedStock != null ? affectedStock.getId() : "null");
            
            // 创建连锁变化记录
            CostWeightChangeSource chainChange = new CostWeightChangeSource();
            chainChange.setStockId(affectedStock != null ? affectedStock.getId() : null);
            chainChange.setCommodityId(affectedStock != null ? affectedStock.getCommodityId() : null);
            chainChange.setCommodityName(affectedStock != null ? affectedStock.getCommodityName() : null);
            
            // 添加空值检查
            if (originalStock != null && affectedStock != null) {
                chainChange.setBeforeCostWeight(originalStock.getCostWeight());
                chainChange.setAfterCostWeight(affectedStock.getCostWeight());
                if (affectedStock.getCostWeight() != null && originalStock.getCostWeight() != null) {
                    chainChange.setChangeAmount(affectedStock.getCostWeight().subtract(originalStock.getCostWeight()));
                } else {
                    chainChange.setChangeAmount(null);
                }
            }
            
            chainChange.setOperateTime(new Date());
            chainChange.setOperatorId(1L);
            chainChange.setOperatorName("系统");
            chainChange.setSourceType(4); // 重新包装（连锁反应）
            chainChange.setRemark("由连锁反应引起的成本变化，源头订单：" + (rootChange != null ? rootChange.getSourceOrderNo() : ""));
            
            log.debug("开始设置连锁变化的ttid");
            if (rootChange != null) {
                chainChange.setSourceOrderId(rootChange.getSourceOrderId());
                chainChange.setSourceOrderNo(rootChange.getSourceOrderNo());
                chainChange.setRelatedCommodityId(rootChange.getCommodityId());
                chainChange.setRelatedCommodityName(rootChange.getCommodityName());
                // 设置追踪事务ID，与源头变化保持一致
                if (rootChange.getTtid() != null) {
                    chainChange.setTtid(rootChange.getTtid());
                    log.info("从rootChange设置ttid成功: {}", rootChange.getTtid());
                } else {
                    log.warn("rootChange的ttid为空");
                    // 尝试生成新的ttid
                    String newTtid = java.util.UUID.randomUUID().toString();
                    chainChange.setTtid(newTtid);
                    log.info("为chainChange生成新的ttid: {}", newTtid);
                }
            } else {
                log.warn("rootChange为空");
                // 尝试生成新的ttid
                String newTtid = java.util.UUID.randomUUID().toString();
                chainChange.setTtid(newTtid);
                log.info("为chainChange生成新的ttid: {}", newTtid);
            }

            // 保存连锁变化记录
            log.debug("准备保存连锁变化记录: {}", chainChange);
            costWeightChangeSourceService.saveOrUpdate(chainChange);
            log.info("连锁成本变化处理完成，保存的记录ID: {}", chainChange.getId());
        } catch (Exception e) {
            log.error("处理连锁成本变化时发生错误", e);
        }
    }

    @Override
    public void findAllAndHandleChainChanges(CostWeightChangeSource changeSource) {
        try {
            // 查找使用当前库存作为原料的打包订单
            List<PackDeliveryDetail> consumerDetails = findConsumerPackDetails(changeSource.getStockId());

            // 为每个消费者处理连锁变化
            for (PackDeliveryDetail consumerDetail : consumerDetails) {
                if (consumerDetail.getDeliveryId() != null) {
                    PackDelivery consumerPack = packDeliveryService.getById(consumerDetail.getDeliveryId());
                    if (consumerPack != null) {
                        // 查找该打包订单使用的原料库存
                        List<PackDeliveryDetail> 原料Details = new ArrayList<>();
                        if (consumerPack.getCommodities() != null) {
                            原料Details = consumerPack.getCommodities().stream()
                                    .filter(detail -> detail.getDetailType() == 0) // 0生产领料耗用
                                    .collect(ArrayList::new, (list, item) -> list.add(item), ArrayList::addAll);
                        }

                        // 查找该打包订单生成的成品库存
                        List<PackDeliveryDetail> 成品Details = new ArrayList<>();
                        if (consumerPack.getFinishCommodities() != null) {
                            成品Details = consumerPack.getFinishCommodities().stream()
                                    .filter(detail -> detail.getDetailType() == 1) // 1生产完工产品
                                    .collect(ArrayList::new, (list, item) -> list.add(item), ArrayList::addAll);
                        }

                        for (PackDeliveryDetail 成品Detail : 成品Details) {
                            if (成品Detail.getStockId() != null) {
                                Stock 成品Stock = stockService.selectById(成品Detail.getStockId());
                                if (成品Stock != null) {
                                    // 检查成品库存的成本是否发生了变化
                                    Stock latestStock = stockService.selectById(成品Stock.getId());
                                    if (latestStock != null &&
                                            latestStock.getCostWeight() != null &&
                                            成品Stock.getCostWeight() != null &&
                                            latestStock.getCostWeight().compareTo(成品Stock.getCostWeight()) != 0) {

                                        // 处理连锁变化
                                        handleChainCostChange(changeSource, latestStock, 成品Stock);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // 查找使用当前库存的销售订单
            List<SalesOrderDetailStock> consumerSales = findConsumerSalesDetails(changeSource.getStockId());

            // 为每个消费者记录关系（销售订单通常不会直接影响其他库存的成本）
            for (SalesOrderDetailStock consumerSale : consumerSales) {
                // 这里可以记录销售订单的使用关系，但不触发进一步的连锁变化
                recordSalesOrderUsage(changeSource, consumerSale);
            }
        } catch (Exception e) {
            log.error("查找并处理所有连锁变化时发生错误", e);
        }
    }

    /**
     * 查找使用指定库存作为原料的打包明细
     */
    private List<PackDeliveryDetail> findConsumerPackDetails(Long stockId) {
        QueryWrapper<PackDeliveryDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stock_id", stockId);
        queryWrapper.eq("detail_type", 0); // 0生产领料耗用
        return packDeliveryDetailMapper.selectList(queryWrapper);
    }

    /**
     * 查找使用指定库存的销售订单明细库存记录
     */
    private List<SalesOrderDetailStock> findConsumerSalesDetails(Long stockId) {
        QueryWrapper<SalesOrderDetailStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("stock_id", stockId);
        return salesOrderDetailStockService.list(queryWrapper);
    }

    /**
     * 记录销售订单使用关系
     */
    private void recordSalesOrderUsage(CostWeightChangeSource changeSource, SalesOrderDetailStock salesOrderDetailStock) {
        try {
            // 创建使用关系记录（可以扩展CostWeightChangeSource类或创建新表来存储这类信息）
            log.info("库存 {} 被销售订单明细 {} 使用", changeSource.getStockId(), salesOrderDetailStock.getDetailId());
        } catch (Exception e) {
            log.error("记录销售订单使用关系时发生错误", e);
        }
    }
}